package org.openkanban.server.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.dozer.DozerBeanMapper;
import org.openkanban.server.dao.KanbanDao;
import org.openkanban.server.domain.Activity;
import org.openkanban.server.domain.Kanban;
import org.openkanban.server.domain.User;
import org.openkanban.server.service.ActivityService;
import org.openkanban.server.service.KanbanService;
import org.openkanban.server.service.UserService;
import org.openkanban.shared.dto.KanbanDto;
import org.openkanban.shared.dto.StatusDto;
import org.openkanban.shared.dto.UserDto;
import org.openkanban.shared.util.CollectionStringTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * standard service implementation of {@code KanbanService}
 */
@Service
public class KanbanServiceDefaultImpl implements KanbanService {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private UserService userService;

    @Autowired
    private KanbanDao kanbanDao;

    @Autowired
    private DozerBeanMapper mapper;

    @Override
    public Kanban getKanban(Long kanbanId) {
	return kanbanDao.getKanbanById(kanbanId);
    }

    @Override
    public List<KanbanDto> getAllByActivityId(Long parentActivityId) {
	return kanbanDao.getAllByActivityId(parentActivityId);
    }

    @Override
    public Kanban createKanban(String title, String description, String effort, Set<Long> kanbanUser) {
	return kanbanDao.createKanban(title, description, effort, kanbanUser);
    }

    @Override
    @Transactional
    public StatusDto removeKanban(Long kanbanId) {
	Activity activity = activityService.getActivityByKanbanId(kanbanId);
	Kanban kanbanToRemove = kanbanDao.getKanbanById(kanbanId);
	activity.getKanbans().remove(kanbanToRemove);
	return kanbanDao.removeKanban(kanbanToRemove);
    }

    @Override
    @Transactional
    public Kanban updateKanban(KanbanDto kanbanDto) {
	Kanban kanban = mapper.map(kanbanDto, Kanban.class);

	CollectionStringTransformer cst = new CollectionStringTransformer(new HashSet<Long>(), kanbanDto.getKanbanUserString());
	kanbanDto.setKanbanUserIds(cst.toCollection());

	if (kanbanDto.getKanbanUserIds() != null) {
	    for (Long userId : kanbanDto.getKanbanUserIds()) {
		if (userId != null) {
		    kanban.getKanbanUser().add(userService.getUser(userId));
		}
	    }
	}
	return kanbanDao.updateKanban(kanban);
    }

    @Override
    public UserDto[] getUser(Long kanbanId) {
	Kanban kanban = getKanban(kanbanId);
	UserDto[] userDtoArray = new UserDto[kanban.getKanbanUser().size()];

	int i = 0;
	for (User user : kanban.getKanbanUser()) {
	    userDtoArray[i] = mapper.map(user, UserDto.class);
	    i++;
	}

	return userDtoArray;
    }

}
